home *** CD-ROM | disk | FTP | other *** search
- ; simple C-like loop macros
- ;
- ; (for initial test iteration form form ... )
- ; value is the value of the last form
- ;
- ; (while test form form ... )
- ; value is the value of the last form
- ;
- ; (do form form ... form (while test))
- ; value is the value of the last form
- ; implicit progn in while clause
- ;
- ; (break form form ... )
- ; exit the innermost loop, returning the value of the last form
- ;
- ; (continue)
- ; skip to the end of the innermost loop
-
- ; (setq |@loopy-final-value@| ... ) should be
- ; (setq |@loopy-final-value@| (values ... ))
-
-
- (defmodule do-macs
-
- (standard trace)
- ()
-
-
- (defmacro for (init test iter . body)
- `(progn ,init
- (while ,test
- ,@body
- ,iter)))
- (export for)
-
- (defun map-range (f s e)
- (if (> s e) ()
- (progn
- (f s)
- (map-range f (+ s 1) e))))
-
- (defmacro dotimes (var start end . body)
- `(map-range
- (lambda (,var) ,@body)
- ,start ,end))
-
- (export map-range dotimes)
-
- (defmacro ++ (form . vals)
- (cond ((atom form)
- `(setq ,form (+ ,form 1)))
- ((eq (car form) 'dynamic)
- `(dynamic-setq ,(cadr form) (+ ,form 1)))
- (t
- `((setter ,(car form)) ,(cadr form) (+ ,form 1)))))
-
- (defmacro -- (form)
- (cond ((atom form)
- `(setq ,form (- ,form 1)))
- ((eq (car form) 'dynamic)
- `(dynamic-setq ,(cadr form) (- ,form 1)))
- (t
- `((setter ,(car form)) ,(cadr form) (- ,form 1)))))
-
- (export ++ --)
-
- (defmacro setf (form val)
- (cond ((atom form)
- `(setq ,form ,val))
- ((eq (car form) 'dynamic)
- `(dynamic-setq ,(cadr form) ,val))
- (t
- `(let ((@-woo-woo-@ ,val))
- ((setter ,(car form)) ,@(cdr form) @-woo-woo-@)
- @-woo-woo-@))))
-
- (export setf)
-
-
- (defmacro break forms
- `(@break-cont@ (progn ,@forms)))
-
- (defmacro continue ()
- `(@continue-cont@ '(() t)))
-
- (defmacro while (pred . forms)
- `(let/cc @break-cont@
- (map-while (lambda (@continue-cont@) ,@forms)
- (lambda () ,pred)
- ())))
-
- (defun map-while (ff pf val)
- (let ((ans (let/cc cc (map-while-cont ff pf cc val))))
- (if (cdr ans)
- (map-while ff pf val)
- (car ans))))
-
- (defun map-while-cont (ff pf cc val)
- (if (pf)
- (map-while-cont ff pf cc (ff cc))
- (cons val ())))
-
- (defmacro docdr (var arglis . body)
- `(when (not (null ,arglis))
- (let ((,var ,arglis)
- (rest (cdr ,arglis)))
- (while ,var
- (when ,var
- ,@body
- (if rest
- (progn
- (setq ,var rest)
- (setq rest (cdr rest)))
- (setq ,var nil)))))))
-
- (export docdr)
-
- (defmacro docollect (var arg-lis . body)
- `(when (not (null ,arg-lis))
- (let ((,var (car ,arg-lis))
- (rest (cdr ,arg-lis))
- (new-lis nil))
- (while ,var
- (when ,var
- (setq new-lis (append new-lis (list (progn ,@body))))
- (if rest
- (progn
- (setq ,var (car rest))
- (setq rest (cdr rest)))
- (setq ,var nil))))
- new-lis)))
-
- (export docollect)
-
- (defmacro docollect-unique (var arg-lis . body)
- `(when (not (null ,arg-lis))
- (let ((,var (car ,arg-lis))
- (rest (cdr ,arg-lis))
- (new-lis nil)
- (temp nil))
- (while ,var
- (when (not (memq (setq temp (progn ,@body)) new-lis))
- (setq new-lis (append new-lis (list temp))))
- (if rest
- (progn
- (setq ,var (car rest))
- (setq rest (cdr rest)))
- (setq ,var nil)))
- new-lis)))
-
- (export docollect-unique)
-
- ;; List macros...
-
- (defmacro push (val st) `(setq ,st (cons ,val ,st)))
-
-
- (defmacro pop (st) `(let ((val (car ,st)))
- (setq ,st (cdr ,st))
- val))
- (export push pop)
-
- (defmacro incf (arg)
- `(setq ,arg (+ 1 ,arg)))
-
- (export incf)
-
- (defmacro decf (arg)
- `(setq ,arg (- ,arg 1)))
-
- (export decf)
-
- (defmacro trap (value . forms)
- `(let/cc escape
- (with-handler (lambda (a b) (escape ,value)) ,@forms)))
-
- (export trap)
-
- (defmacro multiple-setq forms
- (if forms
- `(progn
- (setq ,(car forms) ,(cadr forms))
- (multiple-setq ,@(cddr forms)))
- `(progn nil)))
-
- (export multiple-setq)
-
- (defmacro dolist (var arglist . body)
- `(mapc (lambda (,var) ,@body) ,arglist))
-
- (export dolist)
-
- (defmacro do* (control test-result . body)
- (let ((decl nil) (label (gensym)) (vl nil) (step nil)
- (test (car test-result))
- (result (cdr test-result)))
- (mapc (lambda (c)
- (when (symbolp c) (setq c (list c)))
- (setq vl (cons (list (car c) (cadr c)) vl))
- (unless (not (consp (cddr c)))
- (setq step (cons (car c) step))
- (setq step (cons (caddr c) step))))
- control)
-
- `(let* ,(reverse vl)
- ; ,@decl
- (while (not ,test)
- (progn ,@body)
- (multiple-setq ,@(reverse step)))
- (progn ,@result))))
-
- (export do*)
-
- (export break continue while map-while map-while-cont)
-
- (defmacro prog x `(progn ,@x))
- (export prog)
-
- (defmacro do body
- (let* ((revbody (reverse body))
- (while-clause (car revbody))
- (test (if (and (consp while-clause)
- (eq (car while-clause) 'while))
- (cdr while-clause)
- (list while-clause)))
- (newbody (reverse (cdr revbody))))
- `(let ((@-res-@ nil))
- (while (progn (setq @-res-@ (progn ,@newbody))
- (progn ,@test))
- nil)
- @-res-@)))
-
- (export do)
-
- )
-